package jaux.tank.generator.util;

import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * The Class StringUtil.
 */
public class StringUtil {

	/** The Constant STRIP_PATTERN. */
	private static final Pattern STRIP_PATTERN = Pattern.compile("(^[\\-|_|\\s]+)|([\\-|_|\\s]+$)");
	
	public static final String DEFAULT_JOIN_SEPARATOR = ":";
	
	private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
	
	/**
	 * Instantiates a new string util.
	 */
	private StringUtil() {
	}
	
	/**
	 * 转换字符串string的首字母为大写。
	 * "aaaBbBCcc" -> "AaaBbBCcc"
	 * @param name the string
	 * @return the string
	 */
	public static String upperFirstCase(String name) {
		String strippedName = strip(name);
		if(strippedName.length()==0) {
			return "";
		}
		return strippedName
				.substring(0, 1).toUpperCase() 
				+ (strippedName.length() > 1 ? strippedName.substring(1) : "");
	}

	/**
	 * 从string字符串中移除前面和后面的 空格、_、-。
	 *
	 * @param name the string
	 * @return the string
	 */
	private static String strip(String name) {
		return STRIP_PATTERN.matcher(name).replaceAll("");
	}
	
	/**
	 * 转换字符串string的首字母为小写 。
	 * "AaaBbBCcc" -> "aaaBbBCcc"
	 * @param str the string
	 * @return the string
	 */
	public static String lowerFirstCase(String str) {
		String strippedName = strip(str);
		return strippedName.substring(0, 1).toLowerCase() + strippedName.substring(1);
	}
	
	/**
	 * 转换字符串string为snake case("aaa_bbb_ccc").
	 *
	 * @param string the string
	 * @return the string
	 */
	public static String snakeCase(String string) {
		// like lodash _.snakeCase
		return lowerCase(string)
				.replaceAll("\\s+([a-z])", "_$1") ;
	}

	
	/**
	 * 转换字符串string以空格分开单词，并转换为小写("aaa bbb ccc")。
	 *
	 * @param str the string
	 * @return the string
	 */
	public static String lowerCase(String str) {
		return str.replace("-", " ").replace("_", " ").replaceAll("\\s+", " ")
				.replaceAll("([a-z]|[0-9])([A-Z])", "$1 $2")
				.strip()
				.toLowerCase();
	}
	
	/**
	 * 转换字符串string为kebab case("aaa-bbb-ccc").
	 *
	 * @param str the string
	 * @return the string
	 */
	public static String kebabCase(String str) {
		return lowerCase(str).replaceAll("\\s+([a-z])", "-$1");
	}
	
	/**
	 * 转换字符串string为驼峰写法("aaaBbbCcc")。
	 *
	 * @param str the string
	 * @return the string
	 */
	public static String camelCase(String str) {
		return lowerFirstCase(Arrays.stream(lowerCase(str).split("\\s+")).map(s->upperFirstCase(s)).collect(Collectors.joining()));
	}
	
	/**
	 * 转换字符串string为大驼峰写法("AaaBbbCcc")。
	 *
	 * @param str the string
	 * @return the string
	 */
	public static String pascalCase(String str) {
		return Arrays.stream(lowerCase(str).split("\\s+")).map(s->upperFirstCase(s)).collect(Collectors.joining());
	}
	public static String join(Object[] objects, String separator, boolean ignoreBlank) {
		if(objects==null || objects.length==0) {
			return "";
		}
		return String.join(separator, Arrays.stream(objects)
				.filter(obj->!ignoreBlank ||obj!=null)
				.map(String::valueOf)
				.filter(s->!ignoreBlank || !s.isBlank())
				.toArray(String[]::new));
	}
	public static String join(Object[] objects, String separator) {
		return join(objects, separator, true);
	}
	public static String join(Collection<Object> objects, String separator) {
		return join(objects==null?new Object[0]:objects.toArray(new Object[0]), separator, true);
	}
	public static String join(Object[] objects ) {
		return join(objects, DEFAULT_JOIN_SEPARATOR);
	}
	
	public static String prettyJSON(Object object) throws JsonProcessingException {
		return OBJECT_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(object);
	}
	
	public static String ifEmpty(String str, String defaultStr) {
		return str == null || str.isEmpty() ? defaultStr : str;
	}
	
	public static String ifBlank(String str, String defaultStr) {
		return str == null || str.isBlank() ? defaultStr : str;
	}
	
	public static String htmlEscape(String str) {
		return str.replace("<", "&lt;").replace(">", "&gt;");
	}
	
	public static String javadocEscape(String str) {
		return str.replace("<", "&lt;")
				.replace(">", "&gt;")
				.replace("/", "\\/")
				.replace("\n", "<br>\n");
	}
	
	public static String prefix( String str, String prefix) {
		return prefix + str;
	}
	public static String[] prefix(Object[] objs,String prefix ) {
		return  affix(objs, prefix, "") ;
	}
	public static String[] prefix(Collection<Object> objs,String prefix ) {
		return  affix(objs, prefix, "") ;
	}
	public static String suffix(String str,String suffix ) {
		return  str + suffix ;
	}
	public static String[] suffix(Object[] objs,String suffix ) {
		return  affix(objs, "", suffix) ;
	}
	public static String[] suffix(Collection<Object> objs,String suffix ) {
		return  affix(objs, "", suffix) ;
	}
	public static String affix(String str, String prefix, String suffix) {
		return  prefix+ str + suffix ;
	}
	public static String[] affix(Object[] objs, String prefix, String suffix) {
		return  affix(Arrays.asList(objs), prefix, suffix) ;
	}
	public static String[] affix(Collection<Object> objs, String prefix, String suffix) {
		String[] result = new String[objs.size()];
		Iterator<Object> iterator = objs.iterator();
		int i=0;
		while(iterator.hasNext()) {
			result[i] = affix(String.valueOf(iterator.next()), prefix, suffix);
			i++;
		}
		return  result ;
	}
}
